package cn.learn.jdk8new.lambda;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;

/**
 * @author huangyezhan
 * @version 1.0
 * @date 2021年06月10日18:22
 */
public class ConvertFieldName {

    /**
     * 通过getter的方法引用获取字段名
     */
    public static <T> String convertToFieldName(IGetter<T> fn) throws Exception {
        SerializedLambda lambda     = getSerializedLambda(fn);
        String           methodName = lambda.getImplMethodName();
        String           prefix     = null;
        if (methodName.startsWith("get")) {
            prefix = "get";
        } else if (methodName.startsWith("is")) {
            prefix = "is";
        }
        if (prefix == null) {
            prefix = "";
            System.out.println("无效的getter方法: " + methodName);
        }

        return toLowerCaseFirstOne(methodName.replace(prefix, ""));
    }

    /**
     * 通过setter的方法引用获取字段名
     */
    public static <T, U> String convertToFieldName(ISetter<T, U> fn) throws Exception {
        SerializedLambda lambda     = getSerializedLambda(fn);
        String           methodName = lambda.getImplMethodName();
        if (!methodName.startsWith("set")) {
            System.out.println("无效的setter方法：" + methodName);
        }
        return toLowerCaseFirstOne(methodName.replace("set", ""));
    }

    /**
     * 关键在于这个方法
     */
    public static SerializedLambda getSerializedLambda(Serializable fn) throws Exception {
        // 编译的时候，会自动生成writeReplace这个方法
        Method method = fn.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(Boolean.TRUE);
        return (SerializedLambda) method.invoke(fn);
    }

    /**
     * 字符串首字母转小写
     */
    public static String toLowerCaseFirstOne(String field) {
        if (Character.isLowerCase(field.charAt(0))) {
            return field;
        } else {
            char   firstOne = Character.toLowerCase(field.charAt(0));
            String other    = field.substring(1);
            return firstOne + other;
        }
    }


    public static void main(String[] args) throws Exception {
        String name = ConvertFieldName.convertToFieldName(Person::getId);
        System.out.println(name);

        String s = ConvertFieldName.convertToFieldName(Person::setName);
        System.out.println(s);
    }

}
